package club.jdiy.core.base.domain;

import java.io.Serializable;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import lombok.Getter;

/**
 * JDiy通用分页数据载体.
 *
 * @param <T> 实体类
 * @author ziquee(子秋) QQ号:39886616 主页: http://www.jdiy.club
 * @version 20210611
 */
@Getter
public class Pager<T> implements Serializable {
    /**
     * 当前页码.
     */
    private final int page;
    /**
     * 每页显示记录条数.
     */
    private final int pageSize;
    /**
     * 总页数
     */
    private final int pageCount;
    /**
     * 记录总条数
     */
    private final long rowCount;
    /**
     * 当前页的数据列表
     */
    private final List<T> items;

    public Pager(int page, int pageSize, long rowCount, List<T> items) {
        this.page = page;
        this.pageSize = pageSize;
        this.rowCount = rowCount;
        this.items = items;
        this.pageCount = pageSize == 0
                ? (rowCount < 1 ? 0 : 1)
                : (int) ((rowCount + (pageSize - 1)) / pageSize);
    }

    /**
     * 将当前的Pager转换为目标对象封包.
     * 示例(将数据库查询出来的User分页转换成Vo封包对象,并返回json至客户端)：<br/>
     * <pre>
     * Pager<UserVo> retPager = pager.to(UserVo::new);
     * return Ret.success(retPager);
     * </pre>
     *
     * @param mapper 转换函数
     * @param <X>    要转换为的目标对象类型
     * @return Pager&lt;X&gt;
     * @since JDiy4.0
     */
    public <X> Pager<X> to(Function<? super T, ? extends X> mapper) {
        return new Pager<>(page, pageSize, rowCount,
                items.stream().map(mapper).collect(Collectors.toList()));
    }

    /**
     * 对当前页内的数据实体each循环预处理.
     * 例如：<br/>
     * <pre>
     *     pager.each(it->it.initStore(context));
     * </pre>
     *
     * @param c 预处理函数
     * @return 当前pager自身
     */
    public Pager<T> each(Consumer<T> c) {
        this.items.forEach(c);
        return this;
    }
}
